#pragma once

#include <map>
#include <vector>

#include "datetime/Timestamp.h"
#include "noncopyable.h"

#include "EventLoop.h"

struct pollfd;

namespace learnmuduo
{
class Channel;

///
/// IO Multiplexing with poll(2).
///
/// This class doesn't own the Channel objects.
class Poller : noncopyable {
public:
  using ChannelList = std::vector<Channel *>;

  Poller(EventLoop *loop);
  ~Poller();

  /// Polls the I/O events.
  /// Must be called in the loop thread.
  muduo::Timestamp poll(int timeoutMs, ChannelList *activeChannels);

  /// Changes the interested I/O events.
  /// Must be called in the loop thread.
  void updateChannel(Channel *channel);

  void assertInLoopThread() { ownerLoop_->assertInLoopThread(); }

private:
  void fillActiveChannels(int numEvents, ChannelList *activeChannels) const;

  using PollFdList = std::vector<struct pollfd>;
  using ChannelMap = std::map<int, Channel *>;

  observer_ptr<EventLoop> ownerLoop_;
  PollFdList pollfds_;
  ChannelMap channels_;
};
} // namespace learnmuduo
